import RootStore from "@xkit-yx/im-store-v2";
import V2NIM, { V2NIMConst } from "nim-web-sdk-ng/dist/v2/NIM_UNIAPP_SDK";
import apiUser from "@/api/user";
import { useUserStore } from "@/store/user";
import { toast } from "./toast";

// 定义联系人信息接口
interface ContactInfo {
  chatInfo: any
  contactId: string
  instanceId: string
  channelId: string
  contactType: ContactType
  chatTeamId: string
  isBeingAssigned: number
  unreadCount: number
  contactStatus: ContactStatus
  userType: string
  customerId: string
  startTime: number
  createTime: number
  success: boolean
}

// 会话类型枚举
enum ContactType {
  TEXT_MESSAGE = 10,
  IM_P2P = 20,
  IM_TEAM = 21,
}

// 会话状态枚举
enum ContactStatus {
  INITIATED = 10,
  ASSIGNED = 20,
  ENDED = 30,
  REJECTED = 40,
}

// NIM服务状态管理
let initialized = false;
let lastActivityTime = Date.now();
let currentContactInfo: ContactInfo | null = null;
let initializationInProgress = false;

// 10分钟自动重新登录相关变量
let autoReconnectTimer: ReturnType<typeof setTimeout> | null = null;
const autoReconnectInterval = 10 * 60 * 1000; // 10分钟自动重新登录一次

export function isInitialized(): boolean {
  return initialized && !!uni.$UIKitNIM && !!uni.$UIKitStore;
}

export function isInitializing(): boolean {
  return initializationInProgress;
}

export function getCurrentContactInfo(): ContactInfo | null {
  return currentContactInfo;
}

export function getUnreadCount(): number {
  return currentContactInfo?.unreadCount || 0;
}

export function getContactStatus(): ContactStatus | null {
  return currentContactInfo?.contactStatus || null;
}

// 获取新token的方法
async function getNewToken(): Promise<string> {
  console.log("开始获取新Token...");

  const userStore = useUserStore();
  const deviceId = userStore.getSystemInfo()?.deviceId;

  if (!deviceId) {
    throw new Error("无法获取设备ID");
  }

  const res = await apiUser.customerGuest({
    instanceId: "202508041418101296925888",
    webUuid: deviceId,
  });

  if (!res || !res.result) {
    throw new Error("获取Token失败");
  }

  // 更新存储的imOptions
  uni.setStorageSync("imOptions", res.result);
  console.log("新Token获取成功并已保存");

  return res.result.imAccountToken.token;
}

// 初始化NIM
export async function initialize(): Promise<boolean> {
  if (initializationInProgress) {
    console.log("正在初始化中，等待完成...");
    return false;
  }

  initializationInProgress = true;
  console.log("开始初始化NIM...");

  try {
    // 获取存储的imOptions，如果没有则重新获取
    let imOptions = uni.getStorageSync("imOptions");

    if (!imOptions) {
      console.log("本地没有imOptions，开始获取访客登录信息...");
      const userStore = useUserStore();
      const deviceId = userStore.getSystemInfo()?.deviceId;

      if (!deviceId) {
        console.error("无法获取设备ID");
        return false;
      }

      const res = await apiUser.customerGuest({
        instanceId: "202508041418101296925888",
        webUuid: deviceId,
      });

      if (!res || !res.result) {
        console.error("获取访客登录信息失败");
        return false;
      }

      imOptions = res.result;
      uni.setStorageSync("imOptions", imOptions);
    }

    // 登录NIM - 使用tokenProvider自动处理token刷新
    try {
      await uni.$UIKitNIM.V2NIMLoginService.login(
        imOptions.imAccountToken.account,
        "",
        {
          forceMode: false,
          authType: 1, // 动态Token鉴权方式
          tokenProvider: async (accountId) => {
            console.log("Token provider被调用，accountId:", accountId);
            try {
              // 每次被调用时都获取新的token
              return await getNewToken();
            }
            catch (error) {
              console.error("tokenProvider获取新token失败:", error);
              // 如果获取新token失败，返回当前存储的token作为备用
              const currentImOptions = uni.getStorageSync("imOptions");
              return currentImOptions?.imAccountToken?.token || "";
            }
          },
        },
      );
      console.log("NIM登录成功");
    }
    catch (error: any) {
      console.error("NIM登录失败:", error);

      // 如果是token相关错误，清除本地存储并重试一次
      if (error.code === 102302) {
        console.log("Token过期，清除本地存储重新登录");
        uni.removeStorageSync("imOptions");
        initializationInProgress = false;
        return await initialize();
      }
      return false;
    }

    // 设置登录状态监听
    setupLoginStatusListener();

    console.log("NIM登录成功，开始获取网络会话信息...");

    // 登录成功后，获取网络会话信息
    const result = await startNetworkContact(imOptions);

    if (!result.success) {
      console.warn("获取网络会话信息失败:", result.error);
      if (result.needNewSession) {
        console.log("首次初始化时会话过期是正常的，继续进行");
      }
    }

    // 设置初始化标志
    initialized = true;

    // 启动10分钟自动重新登录定时器
    startAutoReconnectTimer();

    // 添加用户活动监听
    setupUserActivityListeners();

    console.log("NIM初始化成功");
    return true;
  }
  catch (error) {
    console.error("NIM初始化失败:", error);
    toast.error("NIM初始化失败，请重试");
    return false;
  }
  finally {
    initializationInProgress = false;
  }
}

// 计算距离会话过期还有多长时间
function getTimeUntilSessionExpiry(): number {
  const timeSinceLastActivity = Date.now() - lastActivityTime;
  const timeRemaining = autoReconnectInterval - timeSinceLastActivity;
  return Math.max(0, timeRemaining);
}

// 启动基于真实活动时间的重连定时器
function startAutoReconnectTimer(): void {
  console.log(`启动自动重连定时器`);

  // 清除之前的定时器
  if (autoReconnectTimer) {
    clearTimeout(autoReconnectTimer);
    autoReconnectTimer = null;
  }

  // 基于真实的最后活动时间计算重连时机
  const timeUntilExpiry = getTimeUntilSessionExpiry();
  // 提前30秒重连，避免会话过期
  const reconnectTime = Math.max(timeUntilExpiry - 30000, 60000);

  console.log(`距离会话过期还有 ${Math.floor(timeUntilExpiry / 1000)} 秒，将在 ${Math.floor(reconnectTime / 1000)} 秒后重连`);

  autoReconnectTimer = setTimeout(async () => {
    console.log("基于活动时间触发自动重连...");
    await performAutoReconnect();
  }, reconnectTime);
}

// 执行自动重新登录
async function performAutoReconnect(): Promise<void> {
  try {
    console.log("执行自动重新登录...");

    // 获取当前的imOptions
    const imOptions = uni.getStorageSync("imOptions");
    if (!imOptions) {
      console.error("自动重新登录时找不到imOptions");
      return;
    }

    // 重新发起网络会话
    const result = await startNetworkContact(imOptions);

    if (result.success) {
      console.log("自动重新登录成功");
      lastActivityTime = Date.now();

      // 通知UI会话已更新
      uni.$emit("sessionAutoReconnected", currentContactInfo);

      // 重新启动定时器，基于新的活动时间
      startAutoReconnectTimer();
    }
    else if (result.needNewSession) {
      console.log("会话已过期，需要用户重新进入创建新会话");
      // 清除当前会话信息
      currentContactInfo = null;

      // 通知UI会话已过期
      uni.$emit("sessionExpired", { reason: result.error });

      // 不再自动重试，等待用户手动重新进入
    }
    else {
      console.error("自动重新登录失败:", result.error, "，1分钟后重试");
      // 网络错误等问题，短时间后重试
      autoReconnectTimer = setTimeout(async () => {
        await performAutoReconnect();
      }, 60 * 1000); // 1分钟后重试
    }
  }
  catch (error) {
    console.error("自动重新登录出错:", error);
    // 如果出错，1分钟后重试
    autoReconnectTimer = setTimeout(async () => {
      await performAutoReconnect();
    }, 60 * 1000); // 1分钟后重试
  }
}

// 设置登录状态监听
function setupLoginStatusListener(): void {
  if (!uni.$UIKitNIM || !uni.$UIKitNIM.V2NIMLoginService) {
    console.error("NIM未初始化，无法设置登录状态监听");
    return;
  }

  // 监听登录状态变化
  uni.$UIKitNIM.V2NIMLoginService.on("onLoginStatus", (status: number) => {
    console.log("云信登录状态变更:", status);

    // 如果登录状态为未登录或登录失败，重新初始化
    if (status === 0 || status === 3) {
      console.log("检测到登录状态异常，重新初始化");
      initialized = false;
      uni.removeStorageSync("imOptions");
    }
  });

  // 监听被踢事件
  // @ts-expect-error onKicked事件可能不在类型定义中
  uni.$UIKitNIM.V2NIMLoginService.on("onKicked", (data: any) => {
    console.log("账号在其他设备登录，被踢出:", data);
    toast.info("您的账号在其他设备登录，请重新登录");
  });
}

// 清除登录状态监听
function clearLoginStatusListener(): void {
  if (!uni.$UIKitNIM || !uni.$UIKitNIM.V2NIMLoginService) {
    return;
  }

  uni.$UIKitNIM.V2NIMLoginService.off("onLoginStatus", null);
  // @ts-expect-error onKicked事件可能不在类型定义中
  uni.$UIKitNIM.V2NIMLoginService.off("onKicked", null);
}

// 启动网络会话，返回详细状态
export async function startNetworkContact(imOptions: any): Promise<{ success: boolean, needNewSession: boolean, error?: string }> {
  try {
    console.log("开始获取网络会话信息...");

    const response = await apiUser.getNetworkStart({
      channelId: 'cha-202508041418101296925584',
      customerId: imOptions.customerId,
    });

    console.log("getNetworkStart返回数据:", response);
    if (!response || !response.result) {
      // 检查是否是会话过期或隐藏
      if (response?.message?.includes('隐藏') || response?.message?.includes('过期') || response?.code === 'SESSION_EXPIRED') {
        console.log("会话已被隐藏或过期，需要创建新会话");
        return { success: false, needNewSession: true, error: '会话已过期' };
      }
      console.error("获取网络会话信息失败:", response?.message || 'Unknown error');
      return { success: false, needNewSession: false, error: response?.message || '网络错误' };
    }

    // 保存联系人信息
    currentContactInfo = response.result as unknown as ContactInfo;
    console.log("已保存联系人信息:", currentContactInfo);

    // 更新最后活动时间
    lastActivityTime = Date.now();

    // 创建会话
    if (currentContactInfo && currentContactInfo.contactType) {
      const conversationId = createConversationId(imOptions.imAccountToken.account);
      console.log("创建的会话ID:", conversationId);

      if (conversationId && uni.$UIKitStore && uni.$UIKitStore.uiStore) {
        if (typeof uni.$UIKitStore.uiStore.selectConversation === 'function') {
          uni.$UIKitStore.uiStore.selectConversation(conversationId);
        }
        else {
          uni.$UIKitStore.uiStore.selectedConversation = conversationId;
        }

        // 触发联系人状态变更事件
        uni.$emit("contactStatusChange", currentContactInfo);
        return { success: true, needNewSession: false };
      }
    }

    return { success: false, needNewSession: false, error: '会话创建失败' };
  }
  catch (error: any) {
    console.error("开始网络会话出错:", error);
    // 网络错误或其他异常，通常需要重试
    return { success: false, needNewSession: false, error: error.message || '网络异常' };
  }
}

// 创建会话ID
function createConversationId(account: string): string | null {
  if (!currentContactInfo) {
    console.error("无法创建会话ID，联系人信息不存在");
    return null;
  }
  try {
    let contactTypeId = null;
    if (Number(currentContactInfo.contactType) === 30
      || Number(currentContactInfo.contactType) === 21) {
      contactTypeId = 2;
    }
    const conversationId = `${account}|${contactTypeId}|${currentContactInfo.chatInfo.chatTeamId}`;
    console.log("已创建会话ID:", conversationId);
    return conversationId;
  }
  catch (error) {
    console.error("创建会话ID失败:", error);
    return null;
  }
}

// 设置聊天活动监听器（只监听聊天相关活动）
function setupUserActivityListeners(): void {
  console.log("设置聊天活动监听器");

  // 先移除可能存在的旧监听器
  uni.$off("chatActivity");

  const updateLastActivity = () => {
    lastActivityTime = Date.now();
    console.log(`聊天活动更新: ${new Date(lastActivityTime).toLocaleString()}`);
  };

  // 只监听聊天相关活动，不再监听全局pageShow
  uni.$on("chatActivity", updateLastActivity);
  updateLastActivity();
}

// 更新用户活动时间
export function updateActivityTime(): void {
  lastActivityTime = Date.now();
  console.log(`手动更新用户活动时间: ${new Date(lastActivityTime).toLocaleString()}`);
}

// 检查会话是否即将过期或已过期
export function isSessionNearExpiry(): boolean {
  const timeUntilExpiry = getTimeUntilSessionExpiry();
  return timeUntilExpiry < 60000; // 小于1分钟认为即将过期
}

// 确保会话有效（发送消息前调用）
export async function ensureSessionValid(): Promise<boolean> {
  console.log('检查会话是否有效...');
  
  // 如果已经没有联系人信息，说明会话已断开
  if (!currentContactInfo) {
    console.log('没有联系人信息，会话已断开');
    return false;
  }

  // 如果会话即将过期，尝试重连
  if (isSessionNearExpiry()) {
    console.log('会话即将过期，尝试预防性重连...');
    
    const imOptions = uni.getStorageSync("imOptions");
    if (!imOptions) {
      console.error("找不到imOptions，无法重连");
      return false;
    }

    const result = await startNetworkContact(imOptions);
    if (result.success) {
      console.log('预防性重连成功，会话有效');
      lastActivityTime = Date.now(); // 更新活动时间
      return true;
    } else if (result.needNewSession) {
      console.log('需要新会话，当前会话已过期');
      return false;
    } else {
      console.log('重连失败，但可能是网络问题，尝试发送');
      return true; // 网络问题时允许尝试发送
    }
  }

  // 会话仍在有效期内
  console.log('会话仍在有效期内');
  return true;
}

// 发起会话
export async function startConversation(targetId: string, options: any = {}): Promise<string | null> {
  const initialized = await initialize();
  if (!initialized) {
    toast.error("无法初始化NIM，无法发起会话");
    return null;
  }

  try {
    updateActivityTime();

    if (currentContactInfo && uni.$UIKitStore && uni.$UIKitStore.uiStore) {
      const account = uni.$UIKitNIM.V2NIMLoginService.getLoginUser();
      const conversationId = createConversationId(account);

      if (conversationId) {
        if (typeof uni.$UIKitStore.uiStore.selectConversation === 'function') {
          uni.$UIKitStore.uiStore.selectConversation(conversationId);
        }
        else {
          uni.$UIKitStore.uiStore.selectedConversation = conversationId;
        }
        return conversationId;
      }
    }

    return null;
  }
  catch (error) {
    console.error("发起会话失败:", error);
    toast.error("发起会话失败，请重试");
    return null;
  }
}

// 登出NIM
export async function logout(): Promise<void> {
  try {
    // 停止自动重新登录定时器
    if (autoReconnectTimer) {
      clearTimeout(autoReconnectTimer);
      autoReconnectTimer = null;
    }

    // 关闭会话
    if (currentContactInfo?.contactId) {
      await apiUser.closeConversation({
        contactId: currentContactInfo.contactId,
        customerId: uni.$UIKitNIM.V2NIMLoginService.getLoginUser(),
      });
    }

    // 清除登录状态监听
    clearLoginStatusListener();

    // 清除联系人信息
    currentContactInfo = null;

    // 清除存储
    uni.removeStorageSync("imOptions");

    // 重置初始化状态
    initialized = false;

    console.log("NIM登出成功");
  }
  catch (error) {
    console.error("NIM登出失败:", error);
  }
}

// 为了向后兼容，提供一个包含所有函数的默认导出对象
export default {
  isInitialized,
  isInitializing,
  getCurrentContactInfo,
  getUnreadCount,
  getContactStatus,
  initialize,
  startNetworkContact,
  startConversation,
  updateActivityTime,
  logout,
  ensureSessionValid,
  isSessionNearExpiry,
};
